import { forwardRef, useContext, useMemo, useRef, useState } from 'react';
import {
  Button,
  Divider,
  message,
  ModalContext,
  Space,
  Table,
  Tabs,
  type ColumnProps
} from '../../../../functionalComponent';
import { Layout, iup, useRefCallback } from '../../../../util';
import { AttachmentProvider, AttachmentProviderProps, useAttachment } from '../../AttachmentContext';
import {
  AttachmentToolbarProps,
  DownloadRecordModal,
  FileView,
  LabelSelect,
  RemarkModal,
  Toolbar
} from '../../components';
import type { ITableAttachmentProps } from '../../interface';
import { getFileSize } from '../../util';
import './index.less';

const shareTypeOptions = [
  { label: '自己', value: 'self' },
  { label: '人员', value: 'empno' },
  { label: '部门', value: 'dept' }
];

const attachmentCategoryOptions = [
  { label: '单据附件', key: 'attach' },
  { label: '审批后附件', key: 'approvedAttach' }
  // { label: '工作流附件', value: 'workFlowAttach' },
  // { label: '来源单据附件', value: 'oriBizAttach' },
];

type OriginTableAttachmentProps = Pick<
  ITableAttachmentProps,
  'tableStyle' | 'categoryStyle' | 'style' | 'labelConfig' | 'uploadRef'
>;
export const OriginTableAttachment = (props: OriginTableAttachmentProps) => {
  const { style = {}, categoryStyle, tableStyle = {}, uploadRef = useRef(null), labelConfig } = props;
  const {
    beforeUploadValidate,
    accept,
    maxCount,
    disabled,
    actions,
    permission,
    attachmentRecordList,
    loading,
    isReady,
    attachmentFileList,
    approved,
    uploading,
    onUploadStateChange,
    onContentChanged
  } = useAttachment();
  const { ins, params } = useContext(ModalContext);
  // 表格配置项
  const [attachType, setAttachType] = useState('attach');
  const [checkedListMap, setCheckedListMap] = useState<{
    attach: typeof attachmentFileList;
    approvedAttach: typeof attachmentFileList;
  }>({
    attach: [],
    approvedAttach: []
  });
  const checkedList = useMemo(() => checkedListMap[attachType], [checkedListMap, attachType]);
  const [curRow, setCurRow] = useState<object>();
  const [remarkVisible, setRemarkVisible] = useState(false);
  const [downloadRecordVisible, setDownloadRecordVisible] = useState(false);

  const _tableConfig: ColumnProps[] = [
    {
      title: '附件名称',
      dataIndex: 'asrName',
      width: 210,
      flex: 1,
      tooltip: true,
      filter: true,
      render: ({ row }) => {
        const isFail = row.status === 'fail';
        const uploaded = row.status === 'done' || row.status === undefined;
        const isPreview = uploaded && permission?.preview !== 2 && actions.isPreview(row.asrName || row.fileName);
        return (
          <span className={`attachment-flex-center ${isFail ? 'upload-failed' : ''}`}>
            <FileView
              iconPosition="right"
              isPreview={isPreview}
              data={{
                fileName: row.asrName || row.fileName,
                fileSize: row.originFileSize || row.fileSize,
                status: row.status,
                percent: row.percent
              }}
              handlePreview={() => {
                if (permission?.preview === 0) {
                  message.error('没有预览权限，无法预览');
                  return;
                }
                row.asrFid && actions.preview(row.asrFid);
              }}
            />
          </span>
        );
      }
    },
    {
      title: '附件状态',
      dataIndex: 'asrFlag',
      width: 80,
      flex: 1,
      render: ({ value }) => ['未保存', '已保存'][+value]
    },
    {
      title: '标签',
      dataIndex: 'label',
      width: labelConfig?.style?.width || 150,
      flex: 1,
      render: ({ value, row }) => {
        return (
          <LabelSelect
            labelConfig={{
              ...labelConfig,
              defaultValue: value,
              disabled: disabled,
              style: { ...labelConfig?.style, width: '100%' }
            }}
            fileId={row.asrFid}
            onChangeCallback={onContentChanged}
          />
        );
      }
    },
    {
      title: '备注',
      dataIndex: 'asrRemark',
      width: 80,
      flex: 1,
      tooltip: true
    },
    {
      title: '附件大小',
      dataIndex: 'originFileSize',
      width: 80,
      format: {
        type: 'number',
        formatter: ({ value }) => getFileSize(value)
      },
      flex: 1
    },
    {
      title: '上传人',
      dataIndex: 'userName',
      width: 80,
      flex: 1
    },
    {
      title: '上传时间',
      dataIndex: 'asrFilldt',
      width: 150,
      flex: 1,
      render: ({ value }) => value && iup.formatDate(new Date(value), 'YYYY-MM-DD HH:mm:ss')
    },
    // {
    //   title: '共享方式',
    //   dataIndex: 'shareType',
    //   width: 80,
    //   flex: 1,
    //   render: ({ value, row }) => (
    //     <Select
    //       className="share-type-select"
    //       options={shareTypeOptions}
    //       defaultValue={value && value.split(',')[0]}
    //       bordered={false}
    //       onSelect={(v) => handleChangeShareType(v, row).then(getTableAttach)}
    //     />
    //   )
    // },
    // {
    //   title: '共享给',
    //   dataIndex: 'sharedOneName',
    //   width: 80,
    //   flex: 1,
    //   tooltip: true
    // },
    {
      title: '操作',
      dataIndex: 'options',
      flex: 1,
      width: 150,
      fixed: 'right',
      render: ({ row }) => {
        const uploaded = row.status === 'done' || row.status === undefined;
        if (!uploaded) return null;
        return (
          <Space size={0} split={<Divider type="vertical" style={{ borderLeft: '1px solid var(--primary-color)' }} />}>
            <a
              style={{ color: 'var(--primary-color)' }}
              onClick={() => {
                setCurRow(row);
                setRemarkVisible(true);
              }}
            >
              修改备注
            </a>
            <a
              style={{ color: 'var(--primary-color)' }}
              onClick={() => {
                setCurRow(row);
                setDownloadRecordVisible(true);
              }}
            >
              下载记录
            </a>
          </Space>
        );
      }
    }
  ];

  const filterAttachmentCategoryOptions = useMemo(() => {
    if (+approved === 1 || attachmentRecordList?.findIndex((item) => +item.approved === 1) > -1) {
      return attachmentCategoryOptions;
    } else {
      return attachmentCategoryOptions.filter((item) => item.key !== 'approvedAttach');
    }
  }, [approved, attachmentRecordList]);

  const onToolbarClick: AttachmentToolbarProps['onToolbarClick'] = useRefCallback((action) => {
    switch (action) {
      case 'delete':
        if (!checkedList.length) {
          message.warning('请选择至少一行进行删除');
          return;
        }
        if (attachType !== 'approvedAttach' && +approved === 1) {
          message.error('已审批的单据只能删除审批后附件');
          return;
        }
        actions.delete(checkedList);
        break;
      case 'download':
        if (!checkedList.length) {
          message.warning('请选择至少一行进行下载');
        } else {
          actions.download(checkedList);
        }
        break;
      case 'zipDownload':
        actions.zipDownload();
        break;
    }
  });

  const dataSource = useMemo(() => {
    const _checkedList = checkedListMap[attachType];
    const checkedNames: string[] = _checkedList.map((item) => item.fileName);
    return attachmentFileList.map((v) => {
      return {
        ...v,
        checked: checkedNames.includes(v.fileName)
      };
    });
  }, [attachmentFileList, checkedListMap, attachType]);

  const tableConfig = iup.isNullOrEmpty(labelConfig)
    ? _tableConfig.filter((col) => col.dataIndex !== 'label')
    : _tableConfig;
  return (
    <Layout className="iup-table-attachment" style={style} direction="row">
      <Layout.Flex className="iup-table-attachment-content">
        <Toolbar
          accept={accept}
          uploadRef={uploadRef}
          uploading={uploading}
          permission={permission}
          onUploadStateChange={onUploadStateChange}
          onUploaded={onContentChanged}
          onBeforeUpload={beforeUploadValidate}
          isReady={isReady}
          onToolbarClick={onToolbarClick}
        />
        <div style={{ margin: '5px 0 ' }} />
        {filterAttachmentCategoryOptions.length > 1 ? (
          <Tabs
            fitHeight={false}
            size="small"
            defaultActiveKey={filterAttachmentCategoryOptions[0].key}
            items={filterAttachmentCategoryOptions}
            onChange={(v) => setAttachType(v)}
            tabBarStyle={{ backgroundColor: '#F9FAFB', padding: '0 22px 3px' }}
          />
        ) : null}
        <Layout.Flex className="attachment-table-container" style={tableStyle}>
          <Table
            remember={false}
            key={attachType}
            checkbox
            headerMenu={false}
            rowHeight={40}
            loading={loading}
            onCheckedChange={(list) => setCheckedListMap((state) => ({ ...state, [attachType]: list }))}
            columns={tableConfig}
            dataSource={dataSource}
          />
        </Layout.Flex>
        {params?.isModal ? (
          <div style={{ display: 'flex', margin: '15px 5px 5px', justifyContent: 'flex-end' }}>
            <Button onClick={() => params?.handleCancel(ins)} style={{ width: 84, marginRight: 10 }}>
              取消
            </Button>
            <Button onClick={() => params?.handleOk(ins)} type="primary" style={{ width: 84 }}>
              确定
            </Button>
          </div>
        ) : null}
      </Layout.Flex>
      <RemarkModal
        data={curRow}
        visible={remarkVisible}
        disabled={disabled}
        onCancel={() => setRemarkVisible(false)}
        onSaved={onContentChanged}
      />
      <DownloadRecordModal data={curRow} visible={downloadRecordVisible} setVisible={setDownloadRecordVisible} />
    </Layout>
  );
};

export const TableAttachment = forwardRef(
  (
    { tableStyle, categoryStyle, style, labelConfig, uploadRef, ...rest }: Omit<AttachmentProviderProps, 'children'>,
    ref
  ) => {
    return (
      <AttachmentProvider {...rest} ref={ref}>
        <OriginTableAttachment
          style={style}
          tableStyle={tableStyle}
          uploadRef={uploadRef}
          categoryStyle={categoryStyle}
          labelConfig={labelConfig}
        />
      </AttachmentProvider>
    );
  }
);
